Skip to content

TypeAgent chat panel for VS Code#2291

Open
TalZaccai wants to merge 137 commits intomainfrom
talzacc/vscode-shell-chat
Open

TypeAgent chat panel for VS Code#2291
TalZaccai wants to merge 137 commits intomainfrom
talzacc/vscode-shell-chat

Conversation

@TalZaccai
Copy link
Copy Markdown
Contributor

@TalZaccai TalZaccai commented May 4, 2026

TypeAgent chat panel for VS Code

Brings the TypeAgent chat experience into VS Code as a first-class host
alongside the Electron shell. Same dispatcher, same agents, same chat UI ΓÇö
now embedded in VS Code with multi-panel session sharing, a scripted demo
runner, and a polished reconnect/cancel UX.

Branch: talzacc/vscode-shell-chat ┬╖ 85 files ┬╖ ~14.2k / -650 vs main.

VS Code chat experience

  • Sidebar + side-panel chats; multiple panels share one session.
  • Sessions persist across VS Code reload; full history replays on rejoin.
  • Connection ribbon shows live status (Connected / Disconnected / Demo Mode).
  • Chord keybindings: new chat, clear chat, continue demo, cancel demo.
  • Theme-aware (follows the active VS Code theme).

Chat UX polish (shared with Electron shell)

  • Stop button actually aborts the in-flight request and shows ΓÜá Cancelled.
  • Reconnect: single in-place countdown (Disconnected ΓÇö retrying in Ns ┬╖ <error>) instead of error spam in the chat area.
  • IntelliSense in chat-ui webview: ports the shell's partial-completion engine into the shared chat-ui package so the new vscode-shell host gets inline ghost + dropdown, arrow-key cycling, Ctrl+Space re-summon, Tab-snaps-to-first on auto-opened dropdowns, and Enter-submits-typed-text in inline mode.
  • Multi-panel session sharing: when more than one panel is joined to the same conversation, all of them stay in sync ΓÇö peer panels show bubbles, status updates, final metrics, and history-replay state identical to the originator's.
  • Visual polish: shell-style metrics row, JSON syntax highlighting, hover-only timing tooltips, brighter agent-bubble + ANSI contrast, real username, source-keyed avatars driven end-to-end by each agent's manifest emojiChar (forwarded through the agent-server bridge ΓåÆ webview ΓåÆ chat-ui).

Demo runner (vscode-shell)

  • Run a .txt script from any text editor right-click ΓåÆ "Run TypeAgent Demo Script".
  • Lines type themselves character-by-character into the input.
  • @pauseForInput markers stop on a paused state; Ctrl+ΓåÆ continues.
  • Esc cancels at any time ΓÇö paused, between lines, or mid-typing.
  • Status ribbon reflects [Demo Mode (Running)/(Paused)]; pause hint shown as input ghost.
  • No leaked timers, no message corruption from racing key handlers.
  • Sync demoStarting flag closes a startup race when two invocations fire close together during the file-picker await.

(Independent of the shell-side @shell run / @shell break demo improvements in PR #2277 ΓÇö different host, different code path.)

VS Code integrations (new agent actions)

  • Open / create files (newFile writes to disk before opening so the file persists).
  • Switch to the editor, change theme, open settings, etc., via natural language.
  • Conversation management (new / rename / switch) exposed via a new code-vscode-shell sub-schema in the code agent. Opt-in: defaultEnabled: false; new vscode-shell users run @config schema code-vscode-shell on once (documented in ts/packages/vscode-shell/README.md).

New github-cli agent

  • Talk to the gh CLI in natural language (@github-cli list my prs, ΓǪ).
  • Schema generated using the new onboarding CLI-help-crawl workflow ΓÇö same approach can be reused for any other CLI tool.

Package architecture

  • @typeagent/completion-ui is now a zero-runtime-dependency shared widget package. The canonical SearchMenuItem type lives here; agent-dispatcher imports (and re-exports) it for backwards compatibility. Lightweight downstream consumers (Chrome extension, future hosts) no longer drag the entire dispatcher graph through the menu.

Server / dispatcher infrastructure

  • Per-conversation SharedDispatcher in agentServer that multiplexes ClientIO across all clients joined to the same conversation; also bridges processCommand's RPC return value into a server-emitted commandComplete notify so peer panels stay in sync with the originator.
  • DisplayLog captures display events so a freshly-joined client can replay the conversation.
  • Idle conversations evicted by a new ConversationManager.
  • Reasoning engine made configurable (Copilot / Claude).
  • WebSocket server no longer crashes when sending to a closed socket.
  • Schema cleanup per code-review feedback: split the code agent's NewFileAction into NewCodeFileAction / NewMarkdownFileAction / NewTextFileAction so cross-agent newFile collisions don't need defensive dispatcher patches; stripped negative-assertion DO NOT USE walls from action descriptions in favor of positive User: / Agent: examples.

Bug fixes worth calling out

  • Cross-session callId collision in the code agent ΓÇö nextCallId was per-session but the pending-calls map is module-global, so concurrent sessions collided and routed responses to the wrong place. Fixed by making the counter module-global.
  • Stop button previously sent the webview's clientRequestId where the dispatcher expected its own server-side requestId, so cancel did nothing. Now translated correctly.

Verification

  • B4 smoke-test pass across all flows above (single + multi-tab, ghost text, completion cycling, session restore, history replay, demo state, stop button).
  • 3 parallel code-review agent passes; findings actioned (one false positive documented).
  • Prettier across all changed files.

Try it

  1. Start the server: cd ts/packages/agentServer/server && npm start (ws://localhost:8999, ~3 min full init).
  2. Install the extension: cd ts/packages/vscode-shell && npm run deploy:local.
  3. Click the TypeAgent activity-bar icon ΓÇö ribbon should show Connected.
  4. Open a second panel (Ctrl+K Ctrl+T) ΓÇö sessions share live.
  5. Stop the server → single in-place countdown ribbon. Restart → clears.
  6. Right-click ts/packages/shell/demo/vscode_shell_extension_part1.txt → Run TypeAgent Demo Script. Ctrl+→ at pauses; Esc to cancel.

TalZaccai and others added 30 commits April 20, 2026 21:56
Scaffold a VS Code extension that embeds the TypeAgent shell chat:

- Extension host: activation, sidebar WebviewViewProvider, editor
  panel command, agent server lifecycle manager, status bar item
- Webview: chat UI (messages, input, status), WebSocket connection
  to agent server using the same RPC protocol as the shell renderer
- Theming: uses VS Code CSS variables for full theme integration
- esbuild: dual bundle (extension + webview), watch mode support
- Settings: serverUrl, autoStart, serverPort configuration

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the broken raw WebSocket approach with the proper channel-multiplexed
RPC protocol. The agent server uses createWebSocketChannelServer with named
channels (agent-server, dispatcher:<session>, clientio:<session>).

Architecture change:
- Extension host (Node.js) now manages the real RPC connection using
  connectAgentServer() from @typeagent/agent-server-client
- Webview communicates with extension host via postMessage bridge
- Extension host implements ClientIO and forwards display events to webview

Key changes:
- New: agentServerBridge.ts - manages RPC connection + webview bridge
- Removed: agentServerManager.ts (HTTP probe approach didn't work)
- Removed: webview/agentConnection.ts (raw WebSocket didn't match protocol)
- Updated: chatViewProvider.ts - uses bridge instead of server manager
- Updated: webview/main.ts - uses postMessage instead of direct WebSocket
- Updated: chatUI.ts - handles typed display events from the server
- Updated: package.json - adds @typeagent/* workspace dependencies
- Updated: esbuild.mjs - suppresses import.meta.url warning

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… agent progress

- Handle DisplayContent types (string, string[], TypedDisplayContent) properly
- Use appendDisplay mode 'temporary' for replaceable status messages
- Add filter:true to joinSession to only see own request responses
- Show user message immediately on send (no lag waiting for server echo)
- Add commandComplete event to clean up temporary status on finish
- Dedup consecutive identical inline content
- Remove debug logging

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Switch Session: QuickPick to list and switch between sessions
- New Session: Create a named session and switch to it
- Rename Session: Rename the current session
- Delete Session: Pick and delete a non-current session (with confirmation)
- Status bar shows session name instead of truncated ID
- Chat clears and shows notification on session switch
- Commands registered in VS Code command palette (TypeAgent: *)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add reconnectAndJoin fallback when channel conflicts occur during session switch
- Validate session names for uniqueness (case-insensitive) on create and rename
- Trim whitespace from session names

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Align extension UI with the rest of the project's terminology change
from 'session' to 'conversation'. Internal API identifiers (command IDs,
message types, SessionInfo fields) remain unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add isSwitching flag to suppress disconnect handler during intentional
  reconnects (prevents 'Agent channel disconnected' error surfacing)
- Cancel pending auto-reconnect timers in reconnectAndJoin
- Move webview notifications to after the try/finally so they always fire
  regardless of which code path (direct join or reconnect) succeeded

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The agent server's default port changed to 8999 (see server.ts).
Update extension defaults to match.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add 'switching' message type from bridge to webview
- Disable input/send button while a conversation switch is in progress
- Display target conversation name in the status bar and input placeholder
- Add CSS class for the switching state

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- On connect and after every conversation switch, call
  dispatcher.getDisplayHistory() and replay entries through the same
  display channels live messages use (setUserRequest, setDisplay,
  appendDisplay, setDisplayInfo).
- Wrap replay in historyStart/historyEnd messages so the webview can
  mark replayed bubbles with a 'history' class for muted styling.
- Refactor joinSpecificSession to use the join-before-leave pattern
  (matching the shell's sessionManager); this also eliminates the
  channel-already-exists error so reconnectAndJoin is no longer needed.
- Display 'conversation history' / 'now' separators around replayed
  content for clarity.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove '--- conversation history ---' and '--- now ---' separators
- Each user/agent bubble now shows a small timestamp above its content
- Format: HH:MM for today, 'Yesterday HH:MM' for yesterday, 'Mon DD HH:MM' otherwise
- Full datetime shown on hover via title attribute
- Bridge forwards the entry timestamp during history replay; live messages
  default to Date.now()
- History bubbles still rendered muted via the existing .history class

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previously replay sent N postMessages (one per history entry) and live
events could be interleaved mid-replay, causing:
- Long delay rendering history (slow per-entry postMessage round trips)
- User's live messages getting absorbed into history replay flow and
  marked as .history (they appeared grayed out or didn't show correctly)

Fix: send the entire history as a single 'historyReplay' message. The
webview processes all entries synchronously, then marks just those
bubbles with the .history class.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replaying history on every reconnect (which can happen during long LLM
calls) caused the live user message bubble and its incoming response to
appear interleaved with muted duplicates from the replay, making it look
like the original message disappeared.

Track lastReplayedSessionId and only replay when we first join a session
(or switch to a different one).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The agent dispatcher emits help text and other content with ANSI
escape sequences (e.g. for bold/colored text). Previously those raw
sequences were HTML-escaped and shown verbatim, producing output like
'[0m[1m[4mSubcommands' instead of styled text.

Bring rendering in line with the Electron shell:
- ansi_up converts ANSI sequences to <span> with classes
- markdown-it renders markdown DisplayContent (lists, tables, code)
- DOMPurify sanitises the resulting HTML
- Added ANSI color CSS bound to VS Code terminal theme variables and
  basic markdown styles for code/lists/tables/paragraphs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Switch agent bubble background from inactiveSelectionBackground
  (very faint) to input-background with a subtle border for visibility
- Replace VS Code terminal ANSI variables (designed for terminal
  background) with palette tuned to read against the chat bubble in
  both light and dark themes, scoped via body.vscode-light /
  vscode-dark classes
- White / bright-white now map to foreground so they're never
  invisible

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The dispatcher emits @config (and similar) output as text+ANSI primary
with an HTML alternate. The HTML alternate uses hardcoded slate colors
(#1e293b, #64748b, #475569) designed for a light background — they're
nearly invisible on VS Code's dark theme.

Skip the HTML preference and use the text/markdown primary, which our
ANSI/markdown renderer themes correctly via CSS variables.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restore preference for HTML alternates so we get the richer rendering
(emojis, layout, two-column tables) but post-process the HTML to drop
hard-coded color/background/border-color from inline styles before
sanitising. The remaining theme-variable-based CSS then applies, so
content is readable on both light and dark themes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restructured the message DOM so each message is a row with:
- Avatar (circular, 28px) on the outside (right for user, left for agent)
- Header above the bubble showing source · timestamp in dim text
- Bubble itself contains only the message content

Agent avatars use a per-source emoji (browser→🌐, calendar→📅, etc.)
falling back to the source's first letter. User avatar shows 'T' for
now (will become a real username later).

Other tweaks:
- Bubbles get larger border-radius (12px) with a small flat corner on
  the side closest to the avatar, like the shell
- Timestamp format now includes seconds (matches shell '2:14:24 PM')
- System/error messages override the new flex layout to keep their
  centered block style

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- User bubbles now show a 🪶 (sent) icon when posted and flip to ✅
  (done) when the matching commandComplete arrives. Replayed history
  user messages render with ✅ since they already finished.
- Bridge sends a 'userInfo' message (from os.userInfo().username) on
  webview registration; ChatUI uses it for the user avatar initial and
  the bubble header label instead of the hard-coded 'T'/'you'.
- Expanded the agent emoji map to mirror the values declared in each
  agent's manifest (browser 🌐, calendar 📅, code ⚛, github-cli 🐙,
  weather ⛅, etc.), so agent avatars match what the Electron shell
  shows.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The webview now generates a unique requestId for each send, tags the
pending user bubble with it (data-request-id), and passes it to the
extension host. The host forwards it to dispatcher.processCommand and
echoes it back in commandComplete. The webview maps requestId →
bubble in a Map and flips the matching bubble's icon to ✅ on
completion, so concurrent or out-of-order completions are handled
correctly. Falls back to FIFO if a requestId is missing.

Also send commandComplete on the error path so the bubble doesn't
stay stuck on 🪶 if dispatch throws.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Electron shell shows a roadrunner SVG inside the user bubble that
reflects translation/cache state (not request completion). Match that:

- Embed the same roadrunner SVG from the shell's icon.ts and render it
  hidden inside each new live user bubble.
- Forward 'explained' notify events through the bridge (now carrying
  requestId) and surface them in the webview: green if served from a
  named cache, gold if translated by the model, light blue if there
  was nothing to cache. The tooltip mirrors the shell's
  'Translated by X. Explained at Y' phrasing.
- 'grammarRule' notify with success=false recolors the icon to
  cornflowerblue and appends the reason to the tooltip.
- onCommandComplete no longer flips an icon — completion is unrelated
  to translation state — but still cleans up the pending-bubble map.
- onNotify returns whether the event was consumed so we don't also
  surface it as a noisy system message.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two bugs were keeping the roadrunner stuck on the default grey:

1. RequestId is actually an object {requestId, clientRequestId}, not a
   string. The notify forwarder was passing the whole object as the
   bridge message's requestId, so the webview's string lookup never
   matched any bubble. Extract clientRequestId in the bridge before
   broadcasting so the webview can match it against the data-request-id
   it set on the bubble.

2. The icon sat below the bubble text on its own line. Position it
   absolutely in the top-right corner of the bubble (matching the
   Electron shell's '.chat-message-explained-icon' style), reserve
   right padding so it doesn't overlap the message text.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The roadrunner is only meaningful for action translations: pure chat
responses go through the chat agent and never emit an 'explained'
event, so the icon was sitting permanently grey on those bubbles
showing the misleading default 'Waiting for translation…' tooltip.

Start hidden and only reveal it when _applyExplained sets a real
color and tooltip. Bubbles for chat-only requests now show no icon
at all, matching the actual state.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the roadrunner visible on every user bubble (so the layout is
consistent), but use a richer tooltip lifecycle:

- New live bubble: tooltip 'Translating…' (waiting for explained)
- explained event arrives: color green/gold/blue + 'Translated by X.
  Explained at HH:MM:SS' (sets data-explained=true)
- commandComplete arrives without explained (chat agent, system
  command, etc.): tooltip becomes 'No translation (handled directly)'
  and the icon stays muted

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Forward clientRequestId on display events; tag agent bubbles by
  request id so setDisplayInfo and metrics target the right bubble.
- setDisplayInfo now updates the agent bubble's source label to
  `schemaName.actionName` and makes it clickable to expand a
  pretty-printed JSON panel of the action payload (mirrors shell
  swapContent pattern).
- onCommandComplete reads result.metrics (RequestMetrics) and applies
  a multi-line tooltip (Total / Parse / Command / per-action durations)
  to the user and agent bubbles for the request, viewable on hover.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the hover-tooltip metrics with a two-column row inside the
agent bubble that mirrors the Electron shell:
  left:  First Message: <parse>
  right: Action Elapsed Time: <sum>  /  Total Elapsed Time: <duration>
Times are formatted reader-friendly (ms / s) like the shell.

Add lightweight JSON syntax highlighting in the action JSON expand
panel, using VS Code's symbolIcon token color variables (with
sensible fallbacks) so keys, strings, numbers, booleans and null
are color-coded just like in the editor.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- .bubble-metrics is now hidden by default (opacity 0, max-height 0)
  and fades in only when the .message row is hovered, matching the
  user's expectation of a hover-revealed timing display.
- Switch JSON token colors to the more reliably-defined VS Code
  --vscode-debugTokenExpression-* variables for higher visibility
  across themes (still with hardcoded dark fallbacks).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Render the timing row inside the bubble (instead of below it) and
style it as an attached footer:
- background tinted with --vscode-editorWidget-background
- top border separator
- bottom corners rounded to match the bubble
- left/right columns truly aligned via flex (text-align + flex 0 0)

Reveal the footer on bubble hover with combined opacity, max-height
and padding transitions so it visually slides in.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The bridge already includes the dispatcher-resolved sourceIcon (from
each agent's manifest emojiChar) in the broadcast IAgentMessage payload,
but the webview was discarding it and passing undefined to chat-ui. That
forced every bubble through chat-ui's static DEFAULT_AVATAR_MAP fallback,
which means new agents wouldn't show their emoji and changes to a
manifest's emojiChar wouldn't reach the UI without a chat-ui release.

Pass msg.message.sourceIcon through for setDisplay/appendDisplay so the
authoritative manifest-driven icon reaches the bubble. setDisplayInfo
still falls back to chat-ui's avatar map (the dispatcher's IClientIO
.setDisplayInfo signature does not carry sourceIcon) — that's the
remaining narrow case the DEFAULT_AVATAR_MAP exists for.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ment, demo tweaks

- editorCodeActionsSchema.ts: restore inline parameter comments on EditorActionCreateFile while keeping the DEPRECATED banner.
- codeActionHandler.ts: clarify that the shared WebSocket bridges to the Coda VS Code extension (ts/packages/coda).
- vscode_shell_extension_part2.txt: presenter pause tweaks; comment out create-issue/label steps for now.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
completion-ui no longer depends on agent-dispatcher just to import a single SearchMenuItem type. Move the canonical SearchMenuItem definition into completion-ui and have agent-dispatcher import (and re-export) the type from there.

Why: completion-ui is a small DOM widget package consumed by chat-ui (vscode-shell, Chrome extension, future hosts). Declaring agent-dispatcher as a dependency dragged the entire dispatcher graph (Azure SDK, Anthropic SDK, etc.) into every consumer of the menu. Inverting the direction is a 5-LOC change today and unblocks lightweight downstream consumers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@TalZaccai TalZaccai had a problem deploying to development-fork May 5, 2026 21:30 — with GitHub Actions Failure
@TalZaccai TalZaccai temporarily deployed to development-fork May 5, 2026 21:30 — with GitHub Actions Inactive
…rt 5680)

VisualStudioBridge was instantiated per-session in initializeAgentContext, so the second session/conversation to enable the visualStudio agent would call `new WebSocketServer({ port: 5680 })` while the first session's server was already listening, producing:

  bridge WebSocketServer failed on port 5680: Error: listen EADDRINUSE

The failure was logged but not thrown, so subsequent sessions silently lost the bridge (their bridge.client stayed undefined and any action routed through it errored with 'No host plugin connected').

Mirror the pattern used by codeAgent's CodeAgentWebSocketServer: maintain a single module-scoped bridge with a refcount; first initializeAgentContext starts it, subsequent ones reuse it, last closeAgentContext stops it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@TalZaccai TalZaccai marked this pull request as ready for review May 6, 2026 04:26
@TalZaccai TalZaccai temporarily deployed to development-fork May 6, 2026 04:26 — with GitHub Actions Inactive
@TalZaccai TalZaccai had a problem deploying to development-fork May 6, 2026 04:26 — with GitHub Actions Failure
@TalZaccai TalZaccai requested a review from robgruen May 6, 2026 04:30
Comment thread dotnet/autoShell/Services/WindowsWindowService.cs Outdated
Comment thread ts/packages/agents/code/src/vscode/editorCodeActionsSchema.ts Outdated
Comment thread ts/packages/agents/code/src/vscode/vscodeShellActionsSchema.ts Outdated
Comment thread ts/packages/agents/code/src/codeActionHandler.ts
Comment thread ts/packages/dispatcher/dispatcher/src/reasoning/copilot.ts Outdated
Comment thread ts/packages/dispatcher/dispatcher/src/translation/actionSchemaJsonTranslator.ts Outdated
Comment thread ts/packages/dispatcher/dispatcher/src/translation/actionSchemaJsonTranslator.ts Outdated
Comment thread ts/packages/vscode-shell/src/webview/globals.d.ts
Comment thread ts/packages/vscode-shell/src/agentServerBridge.ts
TalZaccai and others added 12 commits May 6, 2026 12:37
- Sort C# DllImports alphabetically in WindowsWindowService.cs
- Strip negative-assertion language from code-general/code-editor descriptions
- fileName literal-union (string | 'untitled') in NewFileAction
- Drop redundant CodeLanguage comment
- Add themeName?: string to ApplyThemeAction
- TODO above hardcoded port 8082 in codeActionHandler
- TODO above conversation-folder migration in conversationManager
- Rename VscodeShellActions -> VSCodeConversationActions (file + type)
  to disambiguate from VS Code's terminal 'shell'
- Revert PlayTrackAction comment to original wording

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
asc parser doesn't accept JSDoc /** */ blocks (only line comments),
so use line-comment form with the same minimal @deprecated content
Rob suggested.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…list

Replace the if-chain that enumerated newConversation/renameConversation/
switchConversation before falling through to the Coda WS bridge with a
single `action.schemaName === 'code-vscode-shell'` check. Adding a new
conversation action no longer requires touching the top-level dispatcher
— only the extracted `executeConversationAction` helper.

Addresses Rob's PR comment on codeActionHandler.ts:307.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ions union

Narrows the parameter from AppAction to the schema union, eliminating
the (action as any).parameters cast and giving each case body fully typed
access to action.parameters. Adds an assertNever default branch so adding
a new action without a corresponding case becomes a compile error.

Matches the typed-union pattern used by email/calendar/markdown/weather/
player/etc.; addresses Rob's underlying concern about magic-string
coupling between schema and dispatcher.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- desktop SwitchToWindowAction: replace USE-THIS / NEVER prompt wall with
  a single User/Agent example (Rob's preferred style).
- code-vscode-shell manifest entry: drop trigger-keyword soup and the
  'Does NOT handle…' negative assertions from the description; keep only
  the positive description.

Manifest entry name 'code-vscode-shell' kept as-is for now since it
persists in opted-in users' user-settings.json (separate breaking-change
consideration).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…dance

Replace the single NewFileAction with three positively-typed actions:
NewCodeFileAction (with CodeFileLanguage enum), NewMarkdownFileAction,
and NewTextFileAction. This follows the schema best-practices doc at
onboarding/src/schemaGen/schemaGenHandler.ts:26-63 — 'shape the schema
into the form the LLM wants to produce' rather than scolding the LLM
away from the wrong action with anti-examples.

The Coda VS Code extension still implements a single 'newFile' handler;
codeActionHandler.ts maps the three new action names back to the wire
protocol and injects the appropriate language ('markdown' / 'plaintext')
for the markdown and text variants. CodeFileLanguage drops 'plaintext'
and 'markdown' (now their own actions) and adds 'css' and 'json'.

Updates:
- codeActionsSchema.ts: 3-way split + CodeFileLanguage enum
- codeSchema.agr: 3 grammar rules with language-specific keywords
- codeSchema.tests.json: rename 4 newFile -> newCodeFile (CSS/Python/JS/JSON)
- editorCodeActionsSchema.ts: update @deprecated to point at new types
- codeActionHandler.ts: wire-name mapping in executeCodeAction

Addresses PR review comment 3193338769.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Removes the 'USE THIS' / 'DO NOT USE' / 'Trigger phrases include' blocks
that Rob flagged as 'attention-seeking' anti-patterns (see schema
best-practices at onboarding/src/schemaGen/schemaGenHandler.ts:26-63).
Replaces each with a single User:/Agent: example pair showing intended
usage. The defensive walls existed to fight cross-schema collisions; the
schema split in the previous commit and the existing schemaName-based
dispatch make them unnecessary.

Files affected:
- codeActionsSchema.ts: ChangeColorThemeAction, SplitEditorAction
- vscodeConversationActionsSchema.ts: New/Rename/Switch ConversationAction
- desktop/actionsSchema.ts: ApplyThemeAction (themeName slot retained)
- github-cli/src/github-cliSchema.ts: IssueViewAction, PrViewAction

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reverts three defensive patches that were layered to mask cross-schema
collisions in the agent schemas. With the schema redesign in place
(NewFileAction split + prompt-wall removal), the LLM no longer needs
these crutches and Rob's concerns about reserved-action and namespace
pollution are addressed.

- reasoning/claude.ts: drop the cross-schema search that probed every
  active validator on Unknown action name and pointed the model at
  matches in OTHER schemas. UnknownAction is a dispatcher-reserved
  action; the previous logic could circumvent intended dispatcher
  routing (Rob review comment 3193470996).
- reasoning/copilot.ts: same revert as claude.ts (Rob comment 3193472316).
- translation/actionSchemaJsonTranslator.ts: drop the dotted-name
  fallback that tolerated schema-qualified actionNames like
  'code.code-editor.createFile'. If the LLM hallucinates dotted
  actionNames, that's a prompt/schema bug to fix at the source, not
  a translator-side guard (Rob comment 3193485117). Also reverts the
  error message that hard-coded specific agent action names ('newFile',
  'createFile') and schema names — restored to the generic form so the
  dispatcher's translator stays agnostic of any specific agent
  (Rob comment 3193491051).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Conflict in messageGroup.ts: kept main's improved cancellation
handling (replace last agent message with '⚠  Cancelled' instead
of appending a separate status), preserved this branch's
agentMessages.length === 0 guard on the 'Command completed'
branch.

Conflict in pnpm-lock.yaml: took main's regenerated lockfile.

Drive-by: drop the 'Never invent a number' / 'Never use placeholders'
negative assertions in github-cli IssueViewAction and PrViewAction
per Rob's prompt-wall feedback. Schema structure (number?, repo?
optional) plus existing User:/Agent: examples already model the
right behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The earlier schema split (NewFileAction -> NewCodeFileAction /
NewMarkdownFileAction / NewTextFileAction) only changed the
LLM-facing surface. The dispatcher-side handler still mapped all
three back to a single 'newFile' wire action so the Coda VS Code
extension didn't have to change.

That mapping was a surprise — the action name on the wire didn't
match the action name in the schema. Push the split through to
Coda so the wire matches the schema 1:1: stack the three case
labels in handleVSCodeActions.ts and derive the language from the
action name (markdown/plaintext) or actionData.language (code).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
logCommandResult was wrapping the metrics assignment in
try { safeMetrics = JSON.parse(JSON.stringify(metrics)) }
catch { safeMetrics = undefined }, but RequestMetrics is an
already-JSON-shaped object and the caller doesn't mutate it
after push — the try cannot fail in practice and safeMetrics
=== undefined is never observed downstream.

Per design-review.md O4. Assign metrics directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants